package cn.jji8.patronSaint.quick.command;

import org.bukkit.Bukkit;
import org.bukkit.command.*;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;

import javax.annotation.Nonnull;
import java.lang.reflect.Constructor;
import java.util.*;


/**
 * 使用命令管理器可以更方便的管理命令，节约写命令补全器和命令执行器的时间。
 * */
@SuppressWarnings("unused")
public class CommandManger implements CommandExecutor, TabCompleter {
    @SuppressWarnings({"rawtypes", "CanBeFinal"})
    static Class CraftServerClass = null; //org.bukkit.craftbukkit.v1_16_R2.CraftServer.class;
    /*
      用于加载这个管理器，请无视这个方法。（不需要你来调用）
      */
    static{
        ArrayList<Exception> list = new ArrayList<>();
        String Version = org.bukkit.Bukkit.getBukkitVersion();
        for(int i=0;i<=4;i++){
            try {
                String s1 = Version.substring(2,4);
                CraftServerClass = Class.forName("org.bukkit.craftbukkit.v1_"+s1+"_R"+i+".CraftServer");
                break;
            } catch (ClassNotFoundException e) {
                list.add(e);
            }
        }
        if(CraftServerClass == null){
            for(Exception e:list){
                e.printStackTrace();
            }
            Bukkit.getLogger().severe("---------------------------------------");
            Bukkit.getLogger().severe("patronSaint依赖库在不受支持的版本的服务器上运行！");
            Bukkit.getLogger().severe("请向作者反馈此问题。");
            Bukkit.getLogger().severe("jji8PlugClub——群：820131534");
            Bukkit.getLogger().severe("作者qq：2801819967");
            Bukkit.getLogger().severe("---------------------------------------");
        }
    }
    /**
     * 简化掉别名的加载并获得命令控制器
     * @param main 插件的主类
     * @param mainCommand 主命令
     * @param authority 执行此命令需要的权限
     * */
    public static CommandManger load(@Nonnull JavaPlugin main,@Nonnull String mainCommand,String authority){
        CommandManger commandManger = load(main,mainCommand);
        commandManger.authority = authority;
        return commandManger;
    }
    /**
     * 简化掉别名和权限的加载并获得命令控制器
     * @param main 插件的主类
     * @param mainCommand 主命令
     * */
    @SuppressWarnings("unused")
    public static CommandManger load(@Nonnull JavaPlugin main, @Nonnull String mainCommand){
        return load(main,mainCommand,new ArrayList<>());
    }
    /**
     * 加载并获得命令控制器
     * @param main 插件的主类
     * @param mainCommand 主命令
     * @param aliases 命令的别名
     * @param authority 执行此命令需要的权限
     * */
    public static CommandManger load(@Nonnull JavaPlugin main,@Nonnull String mainCommand,@Nonnull List<String> aliases,String authority){
        CommandManger commandManger = load(main,mainCommand,aliases);
        assert commandManger != null;
        commandManger.authority = authority;
        return commandManger;
    }
    /**
     * 简化掉权限的加载并获得命令控制器
     * @param main 插件的主类
     * @param mainCommand 主命令
     * @param aliases 命令的别名
     * */
    public static CommandManger load(@Nonnull JavaPlugin main,@Nonnull String mainCommand,@Nonnull List<String> aliases){
        CommandManger commandManger = new CommandManger();
        Class<PluginCommand> clas = PluginCommand.class;
        PluginCommand pluginCommand = null;
        SimpleCommandMap CommandMap = null;
        try {
            //noinspection unchecked
            Object simpleCommandMap = CraftServerClass.getDeclaredMethod("getCommandMap").invoke(Bukkit.getServer());
            CommandMap = simpleCommandMap instanceof SimpleCommandMap ? (SimpleCommandMap)simpleCommandMap : null;
            Constructor<PluginCommand> constructor = clas.getDeclaredConstructor(String.class, Plugin.class);
            constructor.setAccessible(true);
            pluginCommand = constructor.newInstance(mainCommand,main);
            pluginCommand.setExecutor(commandManger);
            pluginCommand.setTabCompleter(commandManger);
            pluginCommand.setAliases(aliases);
        }catch (Exception e) {
            e.printStackTrace();
            main.getLogger().severe("---------------------------------------");
            main.getLogger().severe("patronSaint依赖库在不受支持的版本的服务器上运行！");
            main.getLogger().severe("请向作者反馈此问题。");
            main.getLogger().severe("jji8PlugClub——群：820131534");
            main.getLogger().severe("作者qq：2801819967");
            main.getLogger().severe("---------------------------------------");
        }
        if(pluginCommand!=null&CommandMap!=null){
            CommandMap.register(main.getName(),pluginCommand);
            commandManger.pluginCommand = pluginCommand;
        }else {
            main.getLogger().severe("patronSaint依赖库无法加插件“"+main.getName()+"”的“"+mainCommand+"”命令,你的服务器是我们可以兼容的版本吗？");
            return null;
        }
        return commandManger;
    }

    /**一个命令列表 和调用器**/
    final Set<CommandData> commandSet = new HashSet<>();

    /**默认的命令执行器，当命令没有任何参数时调用**/
    CommandImplement defaul = null;

    /**pluginCommand*/
    PluginCommand pluginCommand = null;

    /**使用命令需要的权限*/
    String authority = null;

    /**消息提示前缀*/
    String MessagePromptPrefix = null;

    private CommandManger(){}

    /**
     * 设置消息提示前缀
     * */
    public void setMessagePromptPrefix(String messagePromptPrefix) {
        MessagePromptPrefix = messagePromptPrefix;
    }
    /**
     * 获取pluginCommand
     * */
    @SuppressWarnings("unused")
    public PluginCommand getPluginCommand() {
        return pluginCommand;
    }
    /**
     * 设置默认的命令执行器，当命令没有任何参数时调用他
     * */
    @SuppressWarnings("unused")
    public void setDefaulCommand(CommandImplement commandImplement){
        defaul = commandImplement;
    }
    /**
     * 添加一个命令
     * @param commandList 用于触发的命令列表{命令1,命令2}命令的第二的参数等于其中一个都会触发命令执行器
     * @param commandImplement 命令执行器
     * @param completion 补全列表{{位置1补全参数},{位置2补全参数},{位置3补全参数}}命令的第二个参数等于commandList的时候的后面补全的参数
     * @param authority 执行此命令需要的权限
     */
    public void addCommand(String[] commandList,CommandImplement commandImplement,String[][] completion,String authority){
        CommandData commandData = new CommandData(commandList,completion,authority,commandImplement);
        commandSet.add(commandData);
    }
    /**
     * 添加一个命令的方法，省去了权限
     * @param commandList 用于触发的命令列表{命令1,命令2}命令的第二的参数等于其中一个都会触发命令执行器
     * @param commandImplement 命令执行器
     * @param completion 补全列表{{位置1补全参数},{位置2补全参数},{位置3补全参数}}命令的第二个参数等于commandList的时候的后面补全的参数
     */
    public void addCommand(String[] commandList,CommandImplement commandImplement,String[][] completion){
        addCommand(commandList,commandImplement,completion,null);
    }
    /**
     * 添加一个命令的方法，省去了completion（补全列表）
     * @param commandList 用于触发的命令列表{命令1,命令2}命令的第二的参数等于其中一个都会触发命令执行器
     * @param commandImplement 命令执行器
     * @param authority 执行此命令需要的权限
     */
    @SuppressWarnings("unused")
    public void addCommand(String[] commandList, CommandImplement commandImplement,String authority){
        addCommand(commandList,commandImplement,new String[][]{},authority);
    }
    /**
     * 添加一个命令的方法，省去了completion（补全列表）和权限
     * @param commandList 用于触发的命令列表{命令1,命令2}命令的第二的参数等于其中一个都会触发命令执行器
     * @param commandImplement 命令执行器
     */
    @SuppressWarnings("unused")
    public void addCommand(String[] commandList, CommandImplement commandImplement){
        addCommand(commandList,commandImplement,new String[][]{});
    }
    /**
     * 删除一个命令。
     * @param command 添加时的commandList中的任意一个命令。
     * @return 返回CommandImplement删除成功 返回null没有这个命令或删除失败
     * */
    @SuppressWarnings("unused")
    public CommandImplement deleteCommand(String command){
        for (CommandData commandData:commandSet){
            if(commandData.ifImplement(command)){
                if(commandSet.remove(commandData)){
                    return commandData.commandImplement;
                }
            }
        }
        return null;
    }
    /**
     * 获取一个命令的执行器
     * @return 返回null没有这个命令
     * */
    @SuppressWarnings("unused")
    public CommandImplement getCommand(String command){
        for(CommandData commandData:commandSet){
            if(commandData.ifImplement(command)){
                return commandData.commandImplement;
            }
        }
        return null;
    }
    /**
     * 发送消息
     * */
    private void sendMessage(CommandSender commandSender,String Message){
        if(MessagePromptPrefix!=null){
            commandSender.sendMessage(MessagePromptPrefix+Message);
        }else {
            commandSender.sendMessage(Message);
        }
    }
    /**
     * 监听器，请无视这个方法。（不需要你来调用）
     **/
    @Override
    public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, String[] strings) {
        if(authority!=null){
            if(!commandSender.hasPermission(authority)){
                sendMessage(commandSender,"§c你没有使用此命令的权限。需要：§e"+authority);
                return true;
            }
        }
        //没有参数时调用defaul
        if(strings.length<1){
            if(defaul!=null){
                defaul.command(commandSender,strings);
            }else {
                sendMessage(commandSender,"§d此命令需要参数。");
            }
            return true;
        }
        //调用全部的commandData
        for(CommandData commandData:commandSet){
            //如果有一个执行了，就结束
            if(commandData.implement(commandSender,strings)){
                return true;
            }
        }
        sendMessage(commandSender,"§d你输入的命令有勿，请重新输入。");
        return true;
    }

    /**
     * 监听器，请无视这个方法。（不需要你来调用）
     * */
    @Override
    public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, String[] strings) {
        if(strings.length<=1){
            List<String> StringList = new ArrayList<>();
            for(CommandData commandData:commandSet){
                Collections.addAll(StringList, commandData.command);
            }
            return StringList;
        }
        for(CommandData commandData:commandSet){
            if(commandData.ifImplement(strings[0])){
                return commandData.TabComplete(commandSender,strings);
            }
        }
        return null;
    }
}
